package ext.wxcp;

import helper.GlobalConfig;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.bean.menu.WxMenuButton;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.http.URIUtil;
import me.chanjar.weixin.cp.api.WxCpConfigStorage;
import me.chanjar.weixin.cp.api.WxCpInMemoryConfigStorage;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.WxCpServiceImpl;
import me.chanjar.weixin.cp.bean.WxCpDepart;
import me.chanjar.weixin.cp.bean.WxCpUser;
import models.admin.AdminUser;
import models.constants.AvailableStatus;
import models.constants.DeletedStatus;
import models.system.Company;
import org.apache.commons.lang3.EnumUtils;
import play.Logger;
import models.enums.WxcpAppType;
import util.common.ConvertUtil;
import util.common.RandomNumberUtil;

import java.util.*;

/**
 * 微信企业号工具类.
 */
public class WeixinCpHelper {

    private static WxCpInMemoryConfigStorage qyWxCpConfigStorage;
    private static WxCpInMemoryConfigStorage bankWxCpConfigStorage;
    private static WxCpInMemoryConfigStorage eciWxCpConfigStorage;

    /**
     * 物业管理wxCp配置.
     */
    private static WxCpConfigStorage getWyWxCpConfigStorage() {
        if (qyWxCpConfigStorage == null) {
            qyWxCpConfigStorage = new WxCpInMemoryConfigStorage();

            qyWxCpConfigStorage.setCorpId(GlobalConfig.WXCP_CORPID);
            qyWxCpConfigStorage.setCorpSecret(GlobalConfig.WXCP_SECRET);  // 设置微信企业号的app corpSecret
            qyWxCpConfigStorage.setAesKey(GlobalConfig.WXCP_WY_AESKEY);      // 设置微信企业号应用的EncodingAESKey
            qyWxCpConfigStorage.setToken(GlobalConfig.WXCP_WY_TOKEN);       // 设置微信企业号应用的token
            qyWxCpConfigStorage.setAgentId(GlobalConfig.WXCP_WY_AGENT_ID);     // 设置微信企业号应用ID
            qyWxCpConfigStorage.setOauth2redirectUri("http://" + GlobalConfig.WEIXIN_BASE_DOMAIN);
        }
        return qyWxCpConfigStorage;
    }

    /**
     * 通过CorpApp得到微信配置.
     */
    public static WxCpConfigStorage getWxCpConfigStorage() {
        return getWxCpConfigStorage(WxcpAppType.WY);
    }


    public static WxCpConfigStorage getWxCpConfigStorage(WxcpAppType wxcpAppType) {
        Logger.info("LOG00010: query wxcpAppType=" + wxcpAppType);
        switch (wxcpAppType) {
            case WY:
                return getWyWxCpConfigStorage();
        }
        return getWyWxCpConfigStorage();
    }


    /**
     * 通过请求的hostname直接得到微信配置信息.
     */
    public static WxCpConfigStorage getWxCpConfigStorage(String appType) {
        if (appType == null) {
            appType = "WY";
        }
        WxcpAppType enuAppType = EnumUtils.getEnum(WxcpAppType.class, appType.toUpperCase());
        if (enuAppType == null) {
            enuAppType = WxcpAppType.WY;
        }

        return getWxCpConfigStorage(enuAppType);
    }

    /**
     * 通过ConfigStore得到微信服务接口.
     */
    public static WxCpService getWxCpService(WxCpConfigStorage wxCpConfigStorage) {
        WxCpServiceImpl wxCpService = new WxCpServiceImpl();
        wxCpService.setWxCpConfigStorage(wxCpConfigStorage);
        return wxCpService;
    }

    public static WxCpService getWxCpService(WxcpAppType appType) {
        return getWxCpService(getWxCpConfigStorage(appType));
    }

    public static WxCpService getWxCpService() {
        return getWxCpService(WxcpAppType.WY);
    }

    /**
     * 生成OAuth2重定向地址. wx55b53c31c687175a
     * https://open.weixin.qq.com/connect/oauth2/authorize?appid=CORPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
     */
    public static String oauth2BuildAuthorizationUrl(WxCpConfigStorage wxCpConfigStorage, String targetUrl, String state) {
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" ;
        url += "appid=" + wxCpConfigStorage.getCorpId();
        url += "&redirect_uri=" + URIUtil.encodeURIComponent(targetUrl);
        url += "&response_type=code";
        url += "&scope=snsapi_base";
        if (state != null) {
            url += "&state=" + state;
        }
        url += "#wechat_redirect";
        return url;
    }

    /**
     * 转换wxCpUser为User.
     */
    public static AdminUser createOrUpdateUserFromWxCpUser(WxCpService wxCpService, Company corp, WxCpUser wxCpUser) throws Exception {
        AdminUser user = AdminUser.findAdminUserBycpUserIdAndComp(wxCpUser.getUserId(),corp);  //userid就是loginName
        if (user == null) {
            user = new AdminUser();
            user.organization = Company.findById(corp.id); //corpApp.corp是缓存对象，必须重新读取.
            user.loginName = wxCpUser.getUserId()+ RandomNumberUtil.generateRandomChars(8);
            user.password = ConvertUtil.toMD5("111111");
            user.cpUserId = wxCpUser.getUserId();
            user.availableStatus = AvailableStatus.AVAILABLE;
            user.createAt = new Date();
        }else {
            user.modifyAt = new Date();
        }
        user.email = wxCpUser.getEmail();
        user.weixinId = wxCpUser.getWeiXinId();
        user.phoneNo = wxCpUser.getMobile();
        user.name = wxCpUser.getName();
        user.position = wxCpUser.getPosition();
        user.deleted = DeletedStatus.UN_DELETED;
        user.save();

        // 重新绑定用户部门.
        List<WxCpDepart> departList = wxCpService.departGet();
        Map<Integer, WxCpDepart> wxCpDepartMap = new HashMap<Integer, WxCpDepart>();
        for (WxCpDepart wxCpDepart : departList) {
            wxCpDepartMap.put(wxCpDepart.getId(), wxCpDepart);
        }

//        user.save();

        return user;
    }

    public static AdminUser findUserFromWxCpUser(WxCpService wxCpService, Company corp, WxCpUser wxCpUser) throws Exception {
        AdminUser user = AdminUser.findAdminUserBycpUserIdAndComp(wxCpUser.getUserId(),corp);
        return user;
    }

    public static WxCpJsapiSignature createJsapiSignature(WxCpConfigStorage wxCpConfigStorage, WxCpService wxCpService,
                                                          String url) throws WxErrorException {
        WxJsapiSignature jsapiSign = wxCpService.createJsapiSignature(url);

        WxCpJsapiSignature myJsapiSignature = new WxCpJsapiSignature();
        myJsapiSignature.timestamp = jsapiSign.getTimestamp();
        myJsapiSignature.noncestr = jsapiSign.getNoncestr();
        myJsapiSignature.url = jsapiSign.getUrl();
        myJsapiSignature.signature = jsapiSign.getSignature();
        myJsapiSignature.appId = wxCpConfigStorage.getCorpId();
        Logger.info("timestamp :" + myJsapiSignature.timestamp + "|noncestr :" + myJsapiSignature.noncestr + "|url :" + myJsapiSignature.url + "|signature :" + myJsapiSignature.signature + "|appId :" + myJsapiSignature.appId);
        return myJsapiSignature;
    }

    /**
     * 更新企业号菜单.
     */
    public static boolean updateCorpAppMenu() {
        boolean isSuccess = true;

        // 生成“企业用户”的菜单
        isSuccess = createWyMenus(WeixinCpHelper.getWxCpService(WxcpAppType.WY));
        Logger.info("LOG00020: createQyMenus = " + isSuccess);

        return isSuccess;
    }

    private static boolean createWyMenus(WxCpService wxCpService) {
        boolean isSuccess = true;
        deleteOldMenu(wxCpService);

        WxMenu wxMenu = new WxMenu();

        List<WxMenuButton> wxMenuButtons = new ArrayList<>();

        String appType = "wy";

        wxMenu.setButtons(wxMenuButtons);
        Logger.info("LOG00170: wxMenu=" + wxMenu.toJson());
        try {
            wxCpService.menuCreate(wxMenu);
        } catch (WxErrorException e) {
            e.printStackTrace();
            Logger.info(e, "创建菜单失败");
            isSuccess = false;
        }
        return isSuccess;
    }

    private static void deleteOldMenu(WxCpService wxCpService) {
        try {
//            wxCpService.menuGet();
            wxCpService.menuDelete();
        } catch (WxErrorException e) {
            Logger.error(e, "删除菜单异常，无视之");
        }
    }

}
